package com.yinshan.calendar;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Point;
import android.graphics.drawable.GradientDrawable;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.yinshan.calendar.adapter.CommAdapter;
import com.yinshan.calendar.bean.DayDesc;
import com.yinshan.calendar.utils.DateTimeHelper;
import com.yinshan.calendar.utils.Utils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * @author limh
 * @function
 * @date 2019/4/8 14:14
 */
public class CalendarDialog extends Dialog {

    public CalendarDialog(@NonNull Context context) {
        super(context, R.style.styleDialog);
    }

    public static class Builder {
        //结果回调
        private OnResultListener onResultListener;
        private OnIntervalListener onIntervalListener;

        private Context context;
        //选中颜色
        private int selectColor = R.color.colorBlue;
        //点击确定自动关闭
        private boolean autoClose = true;
        //是否点击外部取消
        private boolean outCancel = true;

        //是否区间模式
        private boolean isInterval = false;
        //第一个选择的时间
        private Date firstTime = null;
        //选择的第二个时间
        private Date secondTime = null;
        private TextView txtDisplay;
        private TextView txtHint;
        //选中的年月日
        private int year, month, day;
        //当前日历的年月日
        private int currentYear, currentMonth;
        private ArrayList<DayDesc> days = new ArrayList<>();
        private CommAdapter<DayDesc> adapter;
        //当天日期
        private int myYear, myMonth, myDay;

        public Builder(Context context) {
            this.context = context;
            final Calendar c = Calendar.getInstance();
            currentYear = c.get(Calendar.YEAR);
            currentMonth = c.get(Calendar.MONTH) + 1;
            myYear = c.get(Calendar.YEAR);
            myMonth = c.get(Calendar.MONTH) + 1;
            myDay = c.get(Calendar.DAY_OF_MONTH);

            days.clear();
            days.addAll(Utils.getMonths(currentYear, currentMonth));
            for (DayDesc item : days) {
                if (year == item.getYear() && month == item.getMonth() && day == item.getDay()) {
                    firstTime = item.getDate();
                    item.setCheck(true);
                }
            }
        }


        public Builder setDefault(Date date) {
            if (null != date) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(date);
                this.year = calendar.get(Calendar.YEAR);
                this.month = calendar.get(Calendar.MONTH) + 1;
                this.day = calendar.get(Calendar.DAY_OF_MONTH);
            } else {
                this.year = -1;
                this.month = -1;
                this.day = -1;
            }
            if (null != days) {
                for (DayDesc item : days) {
                    if (year == item.getYear() && month == item.getMonth() && day == item.getDay()) {
                        firstTime = item.getDate();
                        item.setCheck(true);
                    }
                }
                if (null != adapter) {
                    adapter.setmData(days);
                }
            }
            return this;
        }

        public Builder setInterval(boolean interval) {
            isInterval = interval;
            return this;
        }

        public Builder setOnResultListener(OnResultListener onResultListener) {
            this.onResultListener = onResultListener;
            return this;
        }

        public Builder setSelectColor(int selectColor) {
            this.selectColor = selectColor;
            return this;
        }

        public Builder setAutoClose(boolean autoClose) {
            this.autoClose = autoClose;
            return this;
        }

        public Builder setOutCancel(boolean outCancel) {
            this.outCancel = outCancel;
            return this;
        }

        public Builder setOnIntervalListener(OnIntervalListener onIntervalListener) {
            this.onIntervalListener = onIntervalListener;
            return this;
        }

        public CalendarDialog create() {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            if (null == inflater) {
                Log.e("CalendarDialog", "dialog create is fail,inflater is null");
                return null;
            }
            View view = inflater.inflate(R.layout.layout_pop_mycalendar, null);
            final CalendarDialog calendarDialog = new CalendarDialog(context);
            calendarDialog.addContentView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            calendarDialog.setCanceledOnTouchOutside(outCancel);
            txtDisplay = view.findViewById(R.id.txt_pop_yearmonth);
            txtDisplay.setText(Utils.getDisplay(currentYear, currentMonth));
            GridView gridView = view.findViewById(R.id.grid_view);
            txtHint = view.findViewById(R.id.txt_hint);
            Button btnYes = view.findViewById(R.id.btn_pop_yes);
            LinearLayout lineYes = view.findViewById(R.id.line_yes);
            if (isInterval) {
                txtHint.setVisibility(View.VISIBLE);
                lineYes.setVisibility(View.GONE);
            } else {
                txtHint.setVisibility(View.GONE);
                lineYes.setVisibility(View.VISIBLE);
            }
            adapter = new CommAdapter<DayDesc>(days, R.layout.layout_item_calendar) {
                @Override
                public void bindView(ViewHolder holder, DayDesc obj, int position) {
                    TextView txtDay = holder.getView(R.id.txt_item_day);
                    LinearLayout lineDay = holder.getView(R.id.line_day);
                    txtDay.setTextSize(14);
                    ViewGroup.LayoutParams lp = txtDay.getLayoutParams();
                    lp.height = Utils.dip2px(context, 54);
                    txtDay.setLayoutParams(lp);
                    if (!isInterval) {
                        if (obj.getThisMonth()) {
                            if (DateTimeHelper.dateEqual(obj.getDate(), firstTime)) {
                                txtDay.setTextColor(ContextCompat.getColor(context, R.color.colorWhite));
                                GradientDrawable bg = (GradientDrawable) txtDay.getBackground();
                                bg.setColor(ContextCompat.getColor(context, selectColor));
                            } else {
                                if (obj.getYear() == myYear && obj.getMonth() == myMonth && obj.getDay() == myDay) {
                                    txtDay.setTextColor(ContextCompat.getColor(context, selectColor));
                                    GradientDrawable bg = (GradientDrawable) txtDay.getBackground();
                                    bg.setColor(ContextCompat.getColor(context, R.color.colorWhite));
                                } else {
                                    txtDay.setTextColor(ContextCompat.getColor(context, R.color.colorBlack));
                                    GradientDrawable bg = (GradientDrawable) txtDay.getBackground();
                                    bg.setColor(ContextCompat.getColor(context, R.color.colorWhite));
                                }
                            }
                        } else {
                            txtDay.setTextColor(ContextCompat.getColor(context, R.color.colorLine));
                            GradientDrawable bg = (GradientDrawable) txtDay.getBackground();
                            bg.setColor(ContextCompat.getColor(context, R.color.colorWhite));
                        }
                    } else {
                        if (null == firstTime && null == secondTime) {
                            lineDay.setBackgroundColor(ContextCompat.getColor(context, R.color.colorWhite));
                            GradientDrawable bg = (GradientDrawable) txtDay.getBackground();
                            bg.setColor(ContextCompat.getColor(context, R.color.colorWhite));
                        } else if (null != firstTime && null == secondTime) {
                            if (firstTime.compareTo(obj.getDate()) == 0) {
                                GradientDrawable bg = (GradientDrawable) txtDay.getBackground();
                                bg.setColor(ContextCompat.getColor(context, selectColor));
                                lineDay.setBackgroundColor(ContextCompat.getColor(context, R.color.colorWhite));
                            } else {
                                GradientDrawable bg = (GradientDrawable) txtDay.getBackground();
                                bg.setColor(ContextCompat.getColor(context, R.color.colorWhite));
                                lineDay.setBackgroundColor(ContextCompat.getColor(context, R.color.colorWhite));
                            }
                        } else {
                            if (DateTimeHelper.dateEqual(obj.getDate(), firstTime) || DateTimeHelper.dateEqual(obj.getDate(), secondTime)) {
                                GradientDrawable bg = (GradientDrawable) txtDay.getBackground();
                                bg.setColor(ContextCompat.getColor(context, selectColor));
                                if (firstTime.compareTo(obj.getDate()) == 0) {
                                    lineDay.setBackgroundResource(R.drawable.ic_right);
                                } else {
                                    lineDay.setBackgroundResource(R.drawable.ic_left);
                                }

                            } else if (!DateTimeHelper.compareDate(obj.getDate(), firstTime) && DateTimeHelper.compareDate(obj.getDate(), secondTime)) {
                                GradientDrawable bg = (GradientDrawable) txtDay.getBackground();
                                bg.setColor(ContextCompat.getColor(context, R.color.colorLightBlue));
                                lineDay.setBackgroundColor(ContextCompat.getColor(context, R.color.colorLightBlue));
                            } else {
                                GradientDrawable bg = (GradientDrawable) txtDay.getBackground();
                                bg.setColor(ContextCompat.getColor(context, R.color.colorWhite));
                                lineDay.setBackgroundColor(ContextCompat.getColor(context, R.color.colorWhite));
                            }
                            if (DateTimeHelper.dateEqual(firstTime, secondTime)) {
                                lineDay.setBackgroundColor(ContextCompat.getColor(context, R.color.colorWhite));
                            }
                        }
                        //设置字体颜色
                        if (obj.getYear() == myYear && obj.getMonth() == myMonth && obj.getDay() == myDay) {
                            if (DateTimeHelper.dateEqual(obj.getDate(), firstTime) || DateTimeHelper.dateEqual(obj.getDate(), secondTime)) {
                                txtDay.setTextColor(ContextCompat.getColor(context, R.color.colorWhite));
                            } else {
                                txtDay.setTextColor(ContextCompat.getColor(context, selectColor));
                            }
                        } else {
                            if (DateTimeHelper.dateEqual(obj.getDate(), firstTime) || DateTimeHelper.dateEqual(obj.getDate(), secondTime)) {
                                txtDay.setTextColor(ContextCompat.getColor(context, R.color.colorWhite));
                            } else {
                                txtDay.setTextColor(ContextCompat.getColor(context, R.color.colorBlack));
                            }
                        }
                    }
                    txtDay.setText(String.format(Locale.CHINESE, "%d", obj.getDay()));
                }
            };
            gridView.setAdapter(adapter);
            gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    if (!isInterval) {
                        if (days.get(position).getThisMonth()) {
                            year = days.get(position).getYear();
                            month = days.get(position).getMonth();
                            day = days.get(position).getDay();
                            firstTime = days.get(position).getDate();
                            adapter.notifyDataSetChanged();
                        }
                    } else {
                        if (null == firstTime && null == secondTime) {
                            firstTime = days.get(position).getDate();
                        } else if (null != firstTime && null == secondTime) {
                            if (DateTimeHelper.dateEqual(firstTime, days.get(position).getDate())) {
                                secondTime = firstTime;
                            } else {
                                if (DateTimeHelper.compareDate(days.get(position).getDate(), firstTime)) {
                                    firstTime = days.get(position).getDate();
                                } else {
                                    secondTime = days.get(position).getDate();
                                }
                            }
                        } else {
                            if (DateTimeHelper.dateEqual(secondTime, days.get(position).getDate())) {
                                firstTime = secondTime;
                            } else if (DateTimeHelper.dateEqual(firstTime, days.get(position).getDate())) {
                                secondTime = firstTime;
                            } else {
                                if (Math.abs(days.get(position).getDate().getTime() - firstTime.getTime()) < Math.abs(days.get(position).getDate().getTime() - secondTime.getTime())) {
                                    firstTime = days.get(position).getDate();
                                } else {
                                    secondTime = days.get(position).getDate();
                                }
                            }
                            if (DateTimeHelper.compareDate(secondTime, firstTime)) {
                                Date tmp = firstTime;
                                firstTime = secondTime;
                                secondTime = tmp;
                            }
                        }
                        adapter.notifyDataSetChanged();
                        if (null != firstTime && null == secondTime) {
                            if (null != txtHint) {
                                txtHint.setText("请选择截至日期");
                            }
                        }
                        if (null != firstTime && null != secondTime) {
                            if (null != txtHint) {
                                txtHint.setVisibility(View.GONE);
                                txtHint.setText("请选择时间段");
                            }
                            new Handler().postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    if (null != onIntervalListener) {
                                        onIntervalListener.onResult(firstTime, secondTime);
                                    }
                                    calendarDialog.dismiss();
                                }
                            }, 1000);
                        }
                    }
                }
            });
            //取消按钮
            view.findViewById(R.id.btn_pop_cancel).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    firstTime = null;
                    secondTime = null;
                    if (null != txtHint && isInterval) {
                        txtHint.setVisibility(View.VISIBLE);
                        txtHint.setText("请选择时间段");
                    }
                    setDefault(null);
                    adapter.notifyDataSetChanged();
                    if (null != onResultListener) {
                        onResultListener.onCancel();
                    }
                    if (null != onIntervalListener) {
                        onIntervalListener.onCancel();
                    }
                }
            });
            //确定按钮
            btnYes.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (null != onResultListener && null != firstTime) {
                        onResultListener.onResult(firstTime);
                    }
                    if (autoClose) {
                        calendarDialog.dismiss();
                    }
                }
            });
            view.findViewById(R.id.img_pop_close).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    calendarDialog.dismiss();
                }
            });
            //上个月
            view.findViewById(R.id.img_pop_month_last).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    currentMonth -= 1;
                    if (currentMonth == 0) {
                        currentMonth = 12;
                        currentYear -= 1;
                    }
                    updateCalendar();
                }
            });
            //上一年
            view.findViewById(R.id.img_pop_year_last).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    currentYear -= 1;
                    updateCalendar();
                }
            });
            //下个月
            view.findViewById(R.id.img_pop_month_next).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    currentMonth += 1;
                    if (currentMonth == 13) {
                        currentMonth = 1;
                        currentYear += 1;
                    }
                    updateCalendar();
                }
            });
            //下一年
            view.findViewById(R.id.img_pop_year_next).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    currentYear += 1;
                    updateCalendar();
                }
            });
            Window window = calendarDialog.getWindow();
            if (null != window) {
                Point point = new Point();
                Display display = ((Activity) this.context).getWindowManager().getDefaultDisplay();
                display.getSize(point);
                WindowManager.LayoutParams lp = window.getAttributes();
                lp.width = Utils.dip2px(context, 110 * 7);
                calendarDialog.getWindow().setAttributes(lp);
            }
            return calendarDialog;
        }


        private void updateCalendar() {
            if (null == adapter) return;
            if (null == days) return;

            days.clear();
            days.addAll(Utils.getMonths(currentYear, currentMonth));
            adapter.notifyDataSetChanged();
            if (null != txtDisplay) {
                txtDisplay.setText(Utils.getDisplay(currentYear, currentMonth));
            }
        }
    }

    public interface OnResultListener {
        void onResult(Date date);

        void onCancel();
    }

    public interface OnIntervalListener {
        void onResult(Date startDate, Date endDate);

        void onCancel();
    }
}
